#include "Qt3DPicker.h"

#include "Mirror2DHandler.h"
#include "CmdManager.h"
#include "Scene.h"
#include "SendPointHandlerBase.h"
#include "SelectHandler3D.h"
#include "OSGNodeMask.h"
#include "Operation/OpAdd.h"
#include "Operation/OpReplace.h"
#include "QtOSGWidget.h"

Mirror2DHandler::Mirror2DHandler()
{
}

Mirror2DHandler::~Mirror2DHandler()
{
}

void Mirror2DHandler::input(const QVariant& data, const QString& rawInput, CommandSource cs)
{
	auto scene = getScene();
	auto widget3D = getWidget();
	auto sph = getSendPointHandler();
	auto selector = qobject_cast<SelectHandler3D*>(getSelectHandler());
	if (data.type() == QVariant::Bool)
	{
		bool esc = !data.toBool();
		if (esc)
		{
			if (m_clones.size() > 0)
			{
				widget3D->pauseRenderThread();
				for (auto clone : m_clones)
				{
					m_ucs->removeChild(clone);
				}
				widget3D->resumeRenderThread();
			}
			selector->clearSelection();
			clearInput();
			emit finished();
			return;
		}
	}

	if (status() == 0)
	{
		if (selector)
		{
			selector->clearSelection();
			selector->beginSelect(D2CurveMask);
			prompt(1, tr("选择对象: "));
		}
		else
		{
			emit finished();
		}
		return;
	}

	if (status() == 1)
	{
		if (selector && selector->done())
		{
			auto selections = selector->selectionSet();
			if (selections.size() > 0)
			{
				auto selection = *selections.begin();
				std::shared_ptr<Ent> ent = std::dynamic_pointer_cast<Ent>(selection);
				auto parent = ent->getParent();
				UCS* ucs = dynamic_cast<UCS*>(parent);
				if (ucs)
				{
					m_ucs = ucs;
				}
				else
				{
					remark(tr("请选择二维图形"));
					emit finished();
					return;
				}

				widget3D->pauseRenderThread();
				for (auto selection : selections)
				{
					std::shared_ptr<Ent2D> ent = std::dynamic_pointer_cast<Ent2D>(selection);
					if (!ent)
						continue;
					auto parent = ent->getParent();
					UCS* ucs = dynamic_cast<UCS*>(parent);
					if (ucs != m_ucs)
						continue;
					auto clone = ent->clone();
					auto clone2D = std::dynamic_pointer_cast<Ent2D>(clone);
					m_origins.push_back(ent);
					m_clones.push_back(clone2D);
					m_ucs->addChild(clone2D); 
				}
				widget3D->resumeRenderThread();

				if (sph)
				{
					sph->setPointMask(CS_LBTNDOWN | CS_MOUSEMOVE);
				}
				enableMouseHandler(MouseHandlerID::PointSender);
				cmdManager()->setPlane((Plane2DKind)m_ucs->getKind());
				prompt(2, tr("指定镜像线的第一点:"));
			}
			else
			{
				emit finished();
			}
		}
		return;
	}

	if(status() == 2)
	{
		osg::Vec3d ucspt;
		if (getPoint2D(*m_ucs, data, rawInput, cs, ucspt))
		{
			if (cs == CS_MOUSEMOVE)
				return;
			m_start = m_end = ucspt;
			auto matrix = m_ucs->getMatrix();
			show3DRubberLine(true);
			set3DRubberLineP1(m_start * matrix);
			set3DRubberLineP2(m_end * matrix);
			prompt(3, tr("指定镜像线的第二点:"));
		}
		return;
	}

	if (status() == 3)
	{
		osg::Vec3d ucspt;
		if (getPoint2D(*m_ucs, data, rawInput, cs, ucspt))
		{
			m_end = ucspt;
			auto matrix = m_ucs->getMatrix();
			set3DRubberLineP2(m_end * matrix);
			mirror();
			if (cs != CS_MOUSEMOVE)
			{
				widget3D->pauseRenderThread();
				for (auto clone : m_clones)
				{
					m_ucs->removeChild(clone);
				}
				widget3D->resumeRenderThread();
				sph->setPointMask(CS_CMDLINE);
				prompt(4,tr("要删除源对象吗？[是(Y)/否(N)]<N>:"));
				return;
			}
		}
		return;
	}

	if (status() == 4)
	{
		enum Action { NoAct,ReplaceOrigin, AddAct};
		Action act = NoAct;
		if (data.type() == QVariant::Bool)
		{
			act = AddAct;
			auto undoStack = scene->undoStack();
		}
		if (data.type() == QVariant::String)
		{
			auto command = data.value<QString>();
			if (command == tr("Y") || command == tr("y"))
			{
				act = ReplaceOrigin;

				// 记录下本次操作
				auto undoStack = scene->undoStack();
			}
			else if (command == tr("N") || command == tr("n"))
			{
				act = AddAct;
			}
		}

		auto undoStack = scene->undoStack();
		switch (act)
		{
		case ReplaceOrigin:
			undoStack->push(new OpReplace(convert(m_origins), convert(m_clones)));
			selector->clearSelection();
			emit finished();
			break;
		case AddAct:
			undoStack->push(new OpAdd(convertToSet(m_clones)));
			selector->clearSelection();
			emit finished();
			break;
		default:
			remark(tr("请输入Y或N"));
			break;
		}
		return;
	}
}

void Mirror2DHandler::mirror()
{
	int entSize = m_clones.size();
	for (int i = 0; i < entSize; i++)
	{
		m_clones[i]->copy(*m_origins[i]);
	}
	for (auto clone : m_clones)
	{
		clone->mirror(m_start, m_end);
	}
}
